﻿using Lzkj.AepCoapCore;

using Microsoft.Extensions.Options;

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;

using Xc.DataAccess.AepCoapCore.Models;
using Xc.DataAccess.Core;
using Xc.DataAccess.Core.Extensions;

namespace Xc.Logics.AepCoap.Services
{
    public  class AepUploadService : IAepUploadService
    {
        private readonly IAepCoapService aepCoapService;
        private readonly IServiceProvider serviceProvider;
        private readonly IOptions<AppSetting> options;

        public AepUploadService(IAepCoapService aepCoapService, IServiceProvider serviceProvider, IOptions<AppSetting> options)
        {
            this.aepCoapService = aepCoapService;
            this.serviceProvider = serviceProvider;
            this.options = options;
        }
        /// <summary>
        /// 更新设备中
        /// </summary>
        /// <param name="isUpdateOld">是否更新旧的设备</param>
        /// <param name="oldDevice">旧的设备列表</param>
        /// <param name="newDevcie">新的设备列表</param>
        /// <param name="action">上传完毕后回调</param>
        /// <returns></returns>
        public async Task UploadAsync(bool isUpdateOld, ObservableCollection<AddDeviceModel> newDevcie, Action<ExecuteResult> action, ObservableCollection<DeviceInfoList> oldDevice = null)
        {

           var actions= newDevcie.Select(dev => new Func<Task>(async () => {
                try
                {
                    DeviceInfoList dd = null;
                    if (oldDevice != null)
                    {
                        dd = oldDevice.Where(p => p.IMEI.Contains(dev.IMEI)).FirstOrDefault();//匹配已有设备
                    }
                    if (dd == null)//新设备直接增加
                    {
                        CreateDeviceModel createDeviceModel = new CreateDeviceModel();
                        createDeviceModel.DeviceName = dev.DeviceNumber;
                        createDeviceModel.ProductId = options.Value.AepInfo.ProductId;
                        createDeviceModel.IMEI = dev.IMEI;
                        if (dev.IMSI != string.Empty)
                        {
                            createDeviceModel.Other.IMSI = dev.IMSI;
                        }
                        var resp = await aepCoapService.CreateDeviceAsync(new BodyDevcie<CreateDeviceModel> { AppKey = options.Value.AepInfo.AppKey, AppSecret = options.Value.AepInfo.AppSecret, MasterKey = options.Value.AepInfo.MasterKey, Body = createDeviceModel });
                        if (resp.IsSuccess)
                        {
                            dev.AddDeviceStatus = resp.Data.msg;
                            action?.Invoke(new ExecuteResult(dev.DeviceNumber, dev.IMEI, dev.IMSI, resp.Data.msg));
                        }
                    }
                    else//设备已存在
                    {
                        string msgStr = "设备已存在";
                        dev.AddDeviceStatus = msgStr;
                        if (isUpdateOld && oldDevice != null)//更新设备
                        {
                            if (!dd.DeviceName.Contains(dev.DeviceNumber))//设备名称与平台不一致
                            {
                                //设备名称与平台已有设备不一致。。。比较时间哪个最新，以哪个为准
                                if (dd.CreateTime1 >= dev.CreateTime || dd.UpdateTime1 >= dev.CreateTime)
                                {
                                    //平台设备创建的时间 比 需要新增设备的生产时间要晚
                                    dev.AddDeviceStatus = msgStr + "，平台数据最新";
                                }
                                else
                                {
                                    CreateDeviceModel model = new CreateDeviceModel();
                                    model.DeviceName = dev.DeviceNumber;
                                    model.ProductId = options.Value.AepInfo.ProductId;
                                    var resp1 = await aepCoapService.UpdateDevice(new UpdateDevcie<CreateDeviceModel> { DevcieId = dd.DeviceId, AppKey = options.Value.AepInfo.AppKey, AppSecret = options.Value.AepInfo.AppSecret, Body = model, MasterKey = options.Value.AepInfo.MasterKey });
                                    if (resp1.IsSuccess)
                                    {
                                        action?.Invoke(new ExecuteResult(dev.DeviceNumber, dev.IMEI, dev.IMSI, resp1.Data.result));
                                        dev.AddDeviceStatus = msgStr + "设备名称修改成功";
                                    }
                                    else
                                    {
                                        dev.AddDeviceStatus = msgStr + resp1.Message;

                                    }
                                }

                                if (dd.IMSI != null && !dd.IMSI.Contains(dev.IMSI))
                                {

                                    if (dd.CreateTime1 >= dev.CreateTime || dd.UpdateTime1 >= dev.CreateTime)
                                    {
                                        //平台设备创建的时间 比 需要新增设备的生产时间要晚
                                        dev.AddDeviceStatus = msgStr + "，平台数据最新";
                                    }
                                    else
                                    {
                                        CreateDeviceModel model = new CreateDeviceModel();
                                        model.ProductId = options.Value.AepInfo.ProductId;
                                        if (dev.IMSI != string.Empty)
                                        {
                                            model.Other.IMSI = dev.IMSI;
                                        }

                                        dev.AddDeviceStatus = msgStr + "设备IMSI修改成功";
                                        var resp1 = await aepCoapService.UpdateDevice(new UpdateDevcie<CreateDeviceModel> { AppKey = options.Value.AepInfo.AppKey, AppSecret = options.Value.AepInfo.AppSecret, MasterKey = options.Value.AepInfo.MasterKey, DevcieId = dd.DeviceId, Body = model });
                                        if (resp1.IsSuccess)
                                        {
                                            action?.Invoke(new ExecuteResult(dev.DeviceNumber, dev.IMEI, dev.IMSI, resp1.Data.result));
                                            dev.AddDeviceStatus = msgStr + "设备名称修改成功";
                                        }
                                        else
                                        {
                                            dev.AddDeviceStatus = msgStr + resp1.Message;

                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception err)
                {
                    dev.AddDeviceStatus = err.Message;

                }
            }));
            System.Collections.Concurrent.ConcurrentQueue<Func<Task>> actions1 = new System.Collections.Concurrent.ConcurrentQueue<Func<Task>>();
            foreach (var item in actions)
            {
                actions1.Enqueue(item);
            }
           List<Task> tasks = new List<Task>();
                for (int i = 0; i < 5; i++)
                {
                    tasks.Add( Task.Factory.StartNew(async () =>
                    {
                           while (actions1.TryDequeue(out var act))
                           {
                              await act.Invoke();
                            await Task.Delay(10);
                           }
                   },TaskCreationOptions.AttachedToParent));
                }
            await Task.WhenAll(tasks);

        }
        /// <summary>
        /// 删除设备
        /// </summary>
        /// <param name="deleteDevice"></param>
        /// <returns></returns>
        public Result DeleteAsync(DeleteDevice deleteDevice)
        {
            return Result.Accept(aepCoapService.DeleteDevice(deleteDevice));
        }
    }
}
